package oop.ex2.compiler;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.*;

import oop.ex2.enums.VariableEnum;

public class LineCompiler {
    ArrayList<Pattern> generalPatterns;
    ArrayList<Pattern> methodPatterns;
    ArrayList<Pattern> variablePatterns;
    ArrayList<Pattern> commentPatterns;
    HashMap<String, String> variables;

    boolean isInsideAComment = false;
    boolean isValidLineGeneral = false;
    String line;

    public LineCompiler() {
        generalPatterns = new ArrayList<Pattern>();
        methodPatterns = new ArrayList<Pattern>();
        variablePatterns = new ArrayList<Pattern>();
        commentPatterns = new ArrayList<Pattern>();
        variables = new HashMap<String, String>();

        createGeneralPatterns();
        createMethodPatterns();
        createVariablesPatterns();
        createCommentsPattern();
    }

    private void createCommentsPattern() {
        commentPatterns.add(Pattern.compile("//.*"));
        commentPatterns.add(Pattern.compile("/\\*.*"));
        commentPatterns.add(Pattern.compile("\\*/.*"));
    }

    private void createVariablesPatterns() {
        variablePatterns.add(Pattern.compile("^String *([A-Za-z]|_+[A-Za-z])"));
        variablePatterns.add(Pattern.compile("^int *([A-Za-z]|_+[A-Za-z])"));
        variablePatterns.add(Pattern.compile("^double *([A-Za-z]|_+[A-Za-z])"));
        variablePatterns.add(Pattern.compile("^char *([A-Za-z]|_+[A-Za-z])"));
        variablePatterns.add(Pattern.compile("^boolean *([A-Za-z]|_+[A-Za-z])"));
        variablePatterns.add(Pattern.compile("([A-Za-z])"));
    }

    private void createMethodPatterns() {
        // TODO Auto-generated method stub

    }

    private void createGeneralPatterns() {
        generalPatterns.add(Pattern.compile(";$"));
        generalPatterns.add(Pattern.compile("\\{$"));
        generalPatterns.add(Pattern.compile("\\}$"));
    }

    public boolean compile(String currrentLine) throws IllegalCodeException {
        line = currrentLine;
//        checkCommentPatterns();
//        if (line.isEmpty()) {
//            return true;
//        }
        

        return true;
    }

    private void checkCommentPatterns() {
        if (!isInsideAComment) {
            for (Pattern currentPattern : commentPatterns) {
                Matcher currentMatcher = currentPattern.matcher(line);
                if (currentMatcher.find()) {
                    if (currentPattern.pattern().equals("\\*/.*")) {
                        isInsideAComment = false;
                    } else if (currentPattern.pattern().equals("//.*")) {
                        line = line.replaceAll(" *//.*", "");
                        System.out.println(line);
                    } else {
                        isInsideAComment = true;
                    }
                }
            }
        }
    }

    private boolean checkMethodPattern() {
        // TODO Auto-generated method stub
        return false;
    }

    private boolean checkVariablePatterns() throws VariablesException {
        if (!isInsideAComment) {
            for (Pattern currentPattern : variablePatterns) {
                Matcher currentMatcher = currentPattern.matcher(line);
                if (currentMatcher.find()) {
                    String[] tempVariable = line.split("=");
                    if (tempVariable.length > 1) {
                        for (int i = 0; i < tempVariable.length; i++) {
                            tempVariable[i] = tempVariable[i].trim();
                        }
                        String[] tempName = tempVariable[0].split(" ");
                        if (tempName.length > 1) {
                            tempVariable[0] = tempName[1];
                        } else {
                            if (!variables.containsKey(tempVariable[0])) {
                                throw new VariablesException("Deffintion of the variable \'" + tempVariable[0]
                                        + "\' not found");
                            }
                        }
                        variables.put(tempVariable[0], tempVariable[1]);
                    }
                    else {
                        if(!variables.containsKey(tempVariable[0])){
                            String[] tempName = tempVariable[0].split(" ");
                            variables.put(tempName[1], "");
                        }
                        else {
                            throw new VariablesException("Variable \'" + tempVariable[0] + "\' already exists");
                        }
                    }
                    return true;
                }
            }
            return false;
        }
        return true;
    }

    private void checkGeneralPatterns() throws GeneralPatternException {
        boolean isValidLine = false;
        if (!isInsideAComment && !line.isEmpty()) {
            for (Pattern currentPattern : generalPatterns) {
                Matcher currentMatcher = currentPattern.matcher(line);
                if (currentMatcher.find()) {
                    line = line.replaceAll(";$", "");
                    line = line.replaceAll("\\{$", "");
                    line = line.replaceAll("\\}$", "");
                    isValidLine = true;
                }
            }
            if (!isValidLine) {
                throw new GeneralPatternException("'{', '}' or ';' is missing in the file " + line);
            }
        }
        isValidLine = false;
    }

}
